home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-22 | 4.0 KB | 188 lines | [TEXT/CWIE] |
- #include "CFIFOQueue.h"
-
- CFIFOQueue::CFIFOQueue(Boolean autoExpand, Boolean onlyLongs)
- {
- fOnlyLongs = onlyLongs;
- fAutoExpand = autoExpand;
-
- fQueueElementSize = sizeof(long);
- fQueueMaxElements = kDefaultQueueSize;
- fQueueElements = 0;
-
- fQueueHead = NewHandle(fQueueElementSize * fQueueMaxElements);
- if (MemError() != noErr)
- throw MemError();
- }
-
-
- CFIFOQueue::CFIFOQueue(long elementSize, long maxElements, Boolean autoExpand, Boolean onlyLongs)
- {
- fOnlyLongs = onlyLongs;
- fAutoExpand = autoExpand;
-
- fQueueElementSize = elementSize;
- fQueueMaxElements = maxElements;
- fQueueElements = 0;
-
- fQueueHead = NewHandle(fQueueElementSize * fQueueMaxElements);
- if (MemError() != noErr)
- throw MemError();
-
- }
-
-
- CFIFOQueue::~CFIFOQueue(void)
- {
- DisposHandle(fQueueHead);
- }
-
-
-
- OSErr CFIFOQueue::SetMaxQueueSize(long maxElements) // Could return an error (-108, or QueueTooBig)
- {
- long theSize;
- OSErr err;
-
- // First an easy check
- if (maxElements < fQueueElements) // Do we have more than that already?
- return (kQueueAlreadyTooBig);
-
- // OK, so now we just try to resize the queue
- theSize = fQueueElementSize * maxElements;
- SetHandleSize(fQueueHead, theSize);
- err = MemError();
-
- if (err == noErr)
- fQueueMaxElements = maxElements;
-
- return (err);
- }
-
-
- long CFIFOQueue::GetMaxQueueSize(void)
- {
- return (fQueueMaxElements);
- }
-
-
-
- long CFIFOQueue::GetQueueElementSize(void)
- {
- return (fQueueElementSize);
- }
-
-
- Boolean CFIFOQueue::AddElement(void *theData) // The address to take data from
- {
- long tryToGrowBy;
- long newQueueCount;
- Size theSize;
- OSErr err;
- Boolean done;
- Boolean result = true; // Assume that we work
-
- if (fQueueElements < (fQueueMaxElements - 1)) // Go ahead and add it, we have space
- AddOneElementToQueue(theData);
- else {
- if (fAutoExpand) // Grow the queue by the default number of elements
- {
- done = false;
- tryToGrowBy = kDefaultQueueSize;
- do {
- try
- {
- newQueueCount = fQueueMaxElements + tryToGrowBy;
- theSize = newQueueCount * fQueueElementSize;
- SetHandleSize(fQueueHead, theSize);
- err = MemError();
- if (err != noErr)
- throw ((OSErr) err);
- fQueueMaxElements = newQueueCount;
- AddOneElementToQueue(theData);
- done = true;
- }
- catch (OSErr error)
- {
- if (tryToGrowBy > 1)
- {
- tryToGrowBy = 1;
- }
- else {
- done = true;
- result = false;
- }
- }
- } while (!done);
- } // if (fAutoExpand)
- else {
- result = false; // Too big, and not allowed to grow, failure
- }
- }
-
- return (result);
- }
-
-
- // theData needs to be storage allocated already for objects, or if fOnlyLongs
- // has been set, then it is the address of a long to store the result in.
- Boolean CFIFOQueue::GetFrontElement(void *theData)
- {
- Ptr topPtr, startPtr;
- long theByteCount;
-
- if (fQueueElements == 0)
- return (false);
-
- if (fOnlyLongs)
- {
- *(long *)theData = **(long**)fQueueHead;
- }
- else {
- BlockMove(*fQueueHead, theData, fQueueElementSize);
- }
-
- fQueueElements--;
- // Now go and shift the elements up in the queue
- if (fQueueElements > 0)
- {
- theByteCount = fQueueElements * fQueueElementSize;
- topPtr = *fQueueHead;
- startPtr = topPtr + fQueueElementSize;
- BlockMoveData(startPtr, topPtr, theByteCount);
- }
-
- return (true);
- }
-
-
-
- long CFIFOQueue::GetQueueLength(void)
- {
- return (fQueueElements);
- }
-
-
- // This method KNOWS that there is enough storage to move something into the queue
- // so it doesn't have to do any additional checking.
- // Please make sure that theData is at least word aligned if you want this to run on
- // a 68000 machine.
- void CFIFOQueue::AddOneElementToQueue(void *theData)
- {
- Ptr destPtr;
-
- if (fOnlyLongs) // We get to cheat and use theData as a long
- {
- (*(long**)fQueueHead)[fQueueElements] = (long) theData;
- }
- else {
- // Figure the offset first for slightly better instruction scheduling on PPC
- destPtr = (Ptr) (fQueueElementSize * fQueueElements);
- destPtr += *fQueueHead;
-
- BlockMoveData(theData, destPtr, fQueueElementSize);
- }
-
- fQueueElements++;
- }
-
-